package deadlock;

/**
 * @author Brook
 */
public class TransferMoneyFixed implements Runnable{

    int flag = 1;
    static Account a = new Account(500);
    static Account b = new Account(500);
    static Object lock = new Object();

    public static void main(String[] args) throws InterruptedException {
        TransferMoneyFixed r1 = new TransferMoneyFixed();
        TransferMoneyFixed r2 = new TransferMoneyFixed();
        r1.flag = 1;
        r2.flag = 0;

        Thread t1 = new Thread(r1);
        Thread t2 = new Thread(r2);
        t1.start();
        t2.start();
        t1.join();
        t2.join();

        System.out.println("a的余钱:"+a.balance);
        System.out.println("b的余钱:"+b.balance);
    }

    @Override
    public void run() {
        if(flag == 1) {
            transferMoney(a,b,200);
        }
        if(flag == 0) {
            transferMoney(b,a,200);
        }
    }

    public static void transferMoney(Account form, Account to, int amount) {

        class Helper {
            public void transfer() {
                if(form.balance - amount < 0) {
                    System.out.println("余额不足，失败");
                }
                form.balance -= amount;
                to.balance = to.balance+ amount;
                System.out.println("转账成功");
            }
        }

        int fromHash = System.identityHashCode(form);
        int toHash = System.identityHashCode(to);
        if(fromHash<toHash){
            synchronized (form) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+":"+form+"开始操作");
                synchronized (to) {
                    new Helper().transfer();
                }
            }
        }else if(fromHash > toHash){
            synchronized (to) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+":"+form+"开始操作");
                synchronized (form) {
                    new Helper().transfer();
                }
            }
        }else {
            synchronized (lock) {
                synchronized (form) {
                    synchronized (to) {
                        new Helper().transfer();
                    }
                }
            }
        }

        synchronized (form){
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+":"+form+"开始操作");
            synchronized (to) {

            }
        }
    }


    static class Account {

        int balance;

        public Account(int balance) {
            this.balance = balance;
        }


    }
}
